/*
 * Copyright (C) 2016 Bilibili
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.bilibili.magicasakura.widgets;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.global.resource.solidxml.Pattern;
import ohos.global.resource.solidxml.TypedAttribute;

import com.bilibili.magicasakura.utils.AttrValue;
import com.bilibili.magicasakura.utils.ThemeUtils;
import com.bilibili.magicasakura.utils.TintInfo;
import com.bilibili.magicasakura.utils.TintManager;

import java.io.IOException;
import java.util.HashMap;

/**
 * @author xyczero617@gmail.com
 * @time 15/9/26
 */
class AppCompatTextHelper extends AppCompatBaseHelper<Text> {

    //If writing like this:
    //int[] ATTRS = { R.attr.tintText, ohos.R.attr.textColor, ohos.R.attr.textColorLink, ...};
    //we can't get textColor value when api is below 20;

    private Color mTextColor;
    private Color mTextLinkColor;

    private TintInfo mTextColorTintInfo;
    private TintInfo mTextLinkColorTintInfo;

    AppCompatTextHelper(Text view, TintManager tintManager) {
        super(view, tintManager);
    }

    @SuppressWarnings("ResourceType")
    @Override
    void loadFromAttribute(AttrSet attrs, int defStyleAttr) {
        if (attrs.getAttr("text_color").isPresent()) {
            setTextColor1(AttrValue.get(attrs, "text_color", ThemeUtils.themeColor));
        }
        if (attrs.getAttr("textColorLink").isPresent()) {
            setLinkTextColor(AttrValue.get(attrs, "textColorLink", ThemeUtils.themeColor));
        }
    }


    /**
     * External use
     */
    public void setTextColor() {
        if (skipNextApply()) return;

        resetTextColorTintResource(mTextLinkColor);
        setSkipNextApply(false);
    }

    /**
     * useless for setLinkTextColor is final
     */
    @Deprecated
    public void setTextLinkColor() {
        if (skipNextApply()) return;

        resetTextLinkColorTintResource(mTextLinkColor);
        setSkipNextApply(false);
    }

    public void setTextAppearanceForTextColor(int attrSet) {
        resetTextColorTintResource(null);
        setTextAppearanceForTextColor(attrSet, true);
    }

    public void setTextAppearanceForTextColor(int resId, boolean isForced) {
        boolean isTextColorForced = isForced || mTextColor == null;

        try {
            Pattern pattern = mView.getContext()
                .getResourceManager()
                .getElement(resId)
                .getPattern();
            HashMap<String, TypedAttribute> hashMap = pattern.getPatternHash();
            for (String name : hashMap.keySet()) {
                TypedAttribute typedAttribute = hashMap.get(name);
                if (name.equals("text_size")) {
//                    mView.setTextSize((int) typedAttribute.getFloatValue());
                } else if (name.equals("text_color")) {
                    setTextColor(new Color(typedAttribute.getColorValue()));
                } else if (name.equals("text_font")) {
//                    mView.setFont(new Font.Builder(typedAttribute.getStringValue()).build());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }
    }

    public void setTextColorByColor(Color color) {
        setTextColor1(color);
    }

    /**
     * Internal use
     *
     * @param tint tint
     */
    private void setTextColor(Color tint) {
        if (skipNextApply()) return;
        mView.setTextColor(tint);
    }

    private void setTextColor1(Color color) {
        if (mTextColor == null || mTextColor.getValue() != color.getValue()) {
            resetTextColorTintResource(color);
            setSupportTextColorTint();
        }
    }

    private void setLinkTextColor(Color color) {
        if (mTextLinkColor.getValue() != color.getValue()) {
            resetTextLinkColorTintResource(color);

            setSupportTextLinkColorTint();
        }
    }

    private void setSupportTextColorTint() {
        if (mTextColorTintInfo == null) {
            mTextColorTintInfo = new TintInfo();
        }
        mTextColorTintInfo.mHasTintColor = true;
        mTextColorTintInfo.mTintColor = mTintManager.getReplaceColorValue(mTextColor);
        applySupportTextColorTint();
    }

    private void setSupportTextLinkColorTint() {
        if (mTextLinkColorTintInfo == null) {
            mTextLinkColorTintInfo = new TintInfo();
        }
        mTextLinkColorTintInfo.mHasTintColor = true;
        mTextLinkColorTintInfo.mTintColor = mTextLinkColor.getValue();
        applySupportTextLinkColorTint();
    }

    private void applySupportTextColorTint() {
        if (mTextColorTintInfo != null && mTextColorTintInfo.mHasTintColor) {
            setTextColor(new Color(mTextColorTintInfo.mTintColor));
        }
    }

    private void applySupportTextLinkColorTint() {
        if (mTextLinkColorTintInfo != null && mTextLinkColorTintInfo.mHasTintColor) {
            //TODO 设置超链接颜色
            mView.setHintColor(new Color(mTextLinkColorTintInfo.mTintColor));
        }
    }

    private void resetTextColorTintResource(Color color) {
        mTextColor = color;
        if (mTextColorTintInfo != null) {
            mTextColorTintInfo.mHasTintColor = false;
            mTextColorTintInfo.mTintColor = 0;
        }
    }

    private void resetTextLinkColorTintResource(Color color) {
        mTextLinkColor = color;
        if (mTextLinkColorTintInfo != null) {
            mTextLinkColorTintInfo.mHasTintColor = false;
            mTextLinkColorTintInfo.mTintColor = 0;
        }
    }

    @Override
    public void tint() {
        if (mTextColor != null) {
            setSupportTextColorTint();
        }
        if (mTextLinkColor != null) {
            setSupportTextLinkColorTint();
        }
    }

    public interface TextExtensible {
        void setTextColorByColor(Color color);
    }
}
